package com.huilian.netty.model;

import com.huilian.netty.constant.CIMConstant;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import lombok.Data;

import java.io.Serializable;
import java.net.SocketAddress;
import java.util.Objects;

/**
 * IoSession包装类,集群时 将此对象存入表中
 */
@Data
public class CIMSession implements Serializable {

	private transient static final long serialVersionUID = 1L;

	public transient static String HOST = "HOST";
	public transient static final int STATE_ENABLED = 0;
	public transient static final int STATE_DISABLED = 1;
	public transient static final int APNS_ON = 1;
	public transient static final int APNS_OFF = 0;

	public transient static String CHANNEL_IOS = "ios";
	public transient static String CHANNEL_ANDROID = "android";
	public transient static String CHANNEL_WINDOWS = "windows";

	private transient Channel session;

	/**
	 * 数据库主键ID
	 */
	private Long id;
	
	/**
	 * session绑定的用户账号
	 */
	private String account;
	/**访客登录账号*/
	private String username;
	
	/**
	 * session在本台服务器上的ID
	 */
	private String nid; 
	
	/**
	 * 客户端ID (设备号码+应用包名),ios为deviceToken
	 */
	private String deviceId; 
	
	/**
	 * session绑定的服务器IP
	 */
	private String host; 
	
	/**
	 * 终端设备类型
	 */
	private String channel; 
	
	/**
	 * 终端设备型号
	 */
	private String deviceModel; 
	
	/**
	 * 终端应用版本
	 */
	private String clientVersion; 
	
	/**
	 * 终端系统版本
	 */
	private String systemVersion; 
	
	/**
	 * 登录时间
	 */
	private Long bindTime; 
	
	/**
	 * 经度
	 */
	private Double longitude; 
	
	/**
	 * 维度
	 */
	private Double latitude; 
	
	/**
	 * 位置
	 */
	private String location; 
	
	/**
	 * APNs推送状态
	 */
	private int apns;
	
	/**
	 * 状态
	 */
	private int state;
	/**员工Id*/
	private int staffId;
	/**连接的类型*/
	private String sentBodyKey;
	/**访客ID*/
	private Integer visitorId;
	/**页面链接*/
	private String pageUrl;
	private Integer appSceneId;


	public void setAppSceneId(Integer appSceneId) {
		this.appSceneId = appSceneId;
		setAttribute(CIMConstant.KEY_APP_SCENE_ID, appSceneId);
	}

	public void setVisitorId(Integer visitorId) {
		this.visitorId = visitorId;
		setAttribute(CIMConstant.KEY_VISITOR_ID, visitorId);
	}

	public void setPageUrl(String pageUrl) {
		this.pageUrl = pageUrl;
		setAttribute(CIMConstant.KEY_VISITOR_TRACK, pageUrl);
	}
	public void setStaffId(int staffId) {
		this.staffId = staffId;
		setAttribute(CIMConstant.KEY_STAFF_ID, staffId);
	}

	public void setSentBodyKey(String sentBodyKey) {
		this.sentBodyKey = sentBodyKey;
		setAttribute(CIMConstant.KEY_SENT_BODY_KEY, sentBodyKey);
	}



	public CIMSession(Channel session) {
		this.session = session;
		this.nid = session.id().asShortText();
	}

	public void setAccount(String account) {
		this.account = account;
		setAttribute(CIMConstant.KEY_ACCOUNT, account);
	}

	public void setusername(String username) {
		this.username = username;
		setAttribute(CIMConstant.KEY_USERNANE, username);
	}

	public void setChannel(String channel) {
		this.channel = channel;
		setAttribute(CIMConstant.KEY_CHANNEL, channel);
	}

	public void setAttribute(String key, Object value) {
		if (session != null) {
			session.attr(AttributeKey.valueOf(key)).set(value);
		}
	}

	public boolean containsAttribute(String key) {
		if (session != null) {
			return session.hasAttr(AttributeKey.valueOf(key));
		}
		return false;
	}

	public Object getAttribute(String key) {
		if (session != null) {
			return session.attr(AttributeKey.valueOf(key)).get();
		}
		return null;
	}

	public void removeAttribute(String key) {
		if (session != null) {
			session.attr(AttributeKey.valueOf(key)).set(null);
		}
	}

	public SocketAddress getRemoteAddress() {
		if (session != null) {
			return session.remoteAddress();
		}
		return null;
	}


	public void write(TextWebSocketFrame data) {
		if (session == null || !session.isActive()) {
			return;
		}
		session.writeAndFlush(data);
	}

	public boolean isConnected() {
		return (session != null && session.isActive()) || state == STATE_ENABLED;
	}

	public void closeNow() {
		if (session != null) {
			session.close();
		}
	}

	public void closeOnFlush() {
		if (session != null) {
			session.close();
		}
	}

	public boolean isIOSChannel() {
		return Objects.equals(channel, CHANNEL_IOS);
	}

	public boolean isAndroidChannel() {
		return Objects.equals(channel, CHANNEL_ANDROID);
	}

	public boolean isWindowsChannel() {
		return Objects.equals(channel, CHANNEL_WINDOWS);
	}

	public boolean isApnsEnable() {
		return Objects.equals(apns, APNS_ON);
	}

	@Override
	public int hashCode() {
		return getClass().hashCode();
	}

	@Override
	public boolean equals(Object o) {
		if (o instanceof CIMSession) {
			CIMSession target = (CIMSession) o;
			return Objects.equals(target.deviceId, deviceId) && Objects.equals(target.nid, nid)
					&& Objects.equals(target.host, host);
		}
		return false;
	}
}
